package com.gym.code.generator.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import com.gym.code.config.admin.bean.method.MethodBaseMappingBean.MethodParameterCombineType;
import com.gym.code.config.admin.bean.method.MethodBaseMappingBean.MethodResultType;
import com.gym.code.generator.AbstractContentGenerator;
import com.gym.code.generator.model.mapping.bean.BeanGenerateModel;
import com.gym.code.generator.model.mapping.field.FieldGenerateModel;
import com.gym.code.generator.model.mapping.field.ParameterFieldGenerateModel;
import com.gym.code.generator.model.mapping.field.ParameterListValueFieldGenerateModel;
import com.gym.code.generator.model.mapping.field.ParameterRangeFieldGenerateModel;
import com.gym.code.generator.model.mapping.layer.LayerGenerateModel;
import com.gym.code.generator.model.mapping.layer.dao.IDaoLayerGenerateModel;
import com.gym.code.generator.model.mapping.layer.service.IServiceLayerGenerateModel;
import com.gym.code.generator.model.mapping.layer.service.ServiceLayerGenerateModel;
import com.gym.code.generator.model.mapping.method.AbstractMethodGenerateModel;
import com.gym.code.generator.model.mapping.method.MethodSelectModel;
import com.gym.code.generator.model.mapping.method.MethodUpdateModel;

/**
 * 
 * @author xinchun.wang 
   @email: 532002108@qq.com
 * @createTime 2015-5-23 下午8:46:31 
 * @param <T>
 */
public abstract class AbstractFaceGenerator<T extends LayerGenerateModel> extends AbstractContentGenerator<T> {
	
	@Override
	protected Set<String> doGenerateImport(LayerGenerateModel bean) {
		Set<String> result = new HashSet<String>();
		List<AbstractMethodGenerateModel> methodModelList = bean.getMethodModelList();
		//遍历每一个方法，引入import
		for(AbstractMethodGenerateModel method : methodModelList) {
			if(method.getMethodParameterType() == MethodParameterCombineType.fixedParamter) {
				List<ParameterFieldGenerateModel> parameterList = method.getParameterList();
				result.addAll(generateParameterImport(parameterList,method.getBeanGenerateModel()));
			} else {
				result.add(generateBeanImport(bean.getBeanGenerateModel()));	
			}
			
		    if(method instanceof MethodSelectModel){
		    	if(MethodResultType.select_bean == ((MethodSelectModel)method).getMethodResultType()){
		    		result.add(generateBeanImport(bean.getBeanGenerateModel()));
		    	} else if(MethodResultType.select_bean_list == ((MethodSelectModel)method).getMethodResultType()){
		    		result.addAll(generateCommonJavaImport());
		    	}
			}
		}
		result.add(generateBeanImport(bean.getBeanGenerateModel()));
		return result;
	}
	
	
	
	protected  final String generateBeanImport(BeanGenerateModel beanGenerateModel){
		return beanGenerateModel.getPackageName() +"."+ beanGenerateModel.getBeanName(); 
	}
	
	protected  Set<String> generateCommonJavaImport(){
		Set<String> result = new HashSet<String>();
		result.add("java.util.List");
		return result;
	}
	
	
	
	protected String getIDaoName(IDaoLayerGenerateModel bean) {
		if(StringUtils.isNotEmpty(bean.getDaoInterfaceName())){
			return bean.getDaoInterfaceName();
		}
		/*if(bean instanceof DaoLayerGenerateModel){
			return "I" +getDaoName((DaoLayerGenerateModel)bean);
		}*/
		return "";
	}
	
	
	protected String getIServiceName(IServiceLayerGenerateModel bean){
		return bean.getServiceInterfaceName();
	}
	
	protected String getServiceName(ServiceLayerGenerateModel bean) {
		if(StringUtils.isNotEmpty(bean.getServiceName())){
			return bean.getServiceName();
		}else {
			return bean.getBeanGenerateModel().getBeanName()+"Service";
		}
	}
	
	/**
	 * 生成方法的参数
	 * @param methodModel
	 * @return
	 */
	protected String generateParameterStr(AbstractMethodGenerateModel methodModel) {
		StringBuilder result = new StringBuilder();
		if(methodModel.getMethodParameterType() == MethodParameterCombineType.beanParameter) {
			result.append(methodModel.getBeanGenerateModel().getBeanName());
			result.append(" bean");
		} else {
			List<ParameterFieldGenerateModel> parameterList = methodModel.getParameterList();
			if(parameterList.size()>0) {
				result.append(wrap(parameterList.toArray(new FieldGenerateModel[0])));
			}
			
			if(methodModel instanceof MethodUpdateModel){
				MethodUpdateModel updateModel = (MethodUpdateModel) methodModel;
				if(result.length() >0){
					result.append(" ,");
				}
				result.append(wrap(updateModel.getUpdateFieldList().toArray(new FieldGenerateModel[0])));
			}
		}
		return result.toString();
	}
	
	
	protected String generateDaoParamertStr(AbstractMethodGenerateModel methodModel) {
		StringBuilder result = new StringBuilder();
		if(methodModel.getMethodParameterType() == MethodParameterCombineType.beanParameter) {
			result.append(methodModel.getBeanGenerateModel().getBeanName());
			result.append(" bean");
		} else {
			List<ParameterFieldGenerateModel> parameterList = methodModel.getParameterList();
			if(parameterList.size()>0) {
				result.append(wrapDaoParameter(parameterList.toArray(new FieldGenerateModel[0])));
			}
			
			if(methodModel instanceof MethodUpdateModel){
				MethodUpdateModel updateModel = (MethodUpdateModel) methodModel;
				if(result.length() >0){
					result.append(" ,");
				}
				result.append(wrapDaoParameter(updateModel.getUpdateFieldList().toArray(new FieldGenerateModel[0])));
			}
		}
		return result.toString();
	}
	
	private StringBuilder wrapDaoParameter (FieldGenerateModel ... parameterList) {
		StringBuilder result = new StringBuilder();
		if(parameterList == null || parameterList.length == 0){
			return result;
		}
		FieldGenerateModel last = parameterList[parameterList.length - 1];
		for (FieldGenerateModel item : parameterList) {
			if(item instanceof ParameterRangeFieldGenerateModel){
				result.append(" ").append(((ParameterRangeFieldGenerateModel)item).getBeginName());
				result.append(",");
				result.append(" ").append(((ParameterRangeFieldGenerateModel)item).getEndName());
			}else if(item instanceof ParameterListValueFieldGenerateModel){
				result.append(item.getPropertyName());
			}else {
				if(item instanceof ParameterFieldGenerateModel){
					ParameterFieldGenerateModel parameterFieldGenerateModel = (ParameterFieldGenerateModel)item;
					if(parameterFieldGenerateModel.getEnumGenerateModel() != null){
						result.append(" ").append(item.getPropertyName());
					} else {
						result.append(" ").append(item.getPropertyName());
					}
				} else {
					result.append(" ").append(item.getPropertyName());
				}
			}
			if(item != last){
				result.append(",");
			}
		}
		return result;
	
	}
	
	private StringBuilder wrap (FieldGenerateModel ... parameterList) {
		StringBuilder result = new StringBuilder();
		if(parameterList == null || parameterList.length == 0){
			return result;
		}
		FieldGenerateModel last = parameterList[parameterList.length - 1];
		for (FieldGenerateModel item : parameterList) {
			if(item instanceof ParameterRangeFieldGenerateModel){
				result.append(item.getValueType().getName()).append(" ").append(((ParameterRangeFieldGenerateModel)item).getBeginName());
				result.append(",");
				result.append(item.getValueType().getName()).append(" ").append(((ParameterRangeFieldGenerateModel)item).getEndName());
			}else if(item instanceof ParameterListValueFieldGenerateModel){
				result.append("List<").append(item.getValueType().getJavaName()).append("> ").append(item.getPropertyName());
			}else {
				if(item instanceof ParameterFieldGenerateModel){
					ParameterFieldGenerateModel parameterFieldGenerateModel = (ParameterFieldGenerateModel)item;
					if(parameterFieldGenerateModel.getEnumGenerateModel() != null){
						result.append(parameterFieldGenerateModel.getEnumGenerateModel().getEnumTypeName()).append(" ").append(item.getPropertyName());
					} else {
						result.append(item.getValueType().getName()).append(" ").append(item.getPropertyName());
					}
				} else {
					result.append(item.getValueType().getName()).append(" ").append(item.getPropertyName());
				}
			}
			if(item != last){
				result.append(",");
			}
		}
		return result;
	
	}
	
	
	protected String generateSelectMethodDeclare(MethodSelectModel methodModel) {
		StringBuilder functionMethodBuilder = new StringBuilder();
		functionMethodBuilder.append("public ");
		if(methodModel.getMethodResultType() == MethodResultType.select_bean){
			functionMethodBuilder.append(methodModel.getBeanGenerateModel().getBeanNameByFirstLetterUpper()).append(" ");
		} else {
			functionMethodBuilder.append("List<").append(methodModel.getBeanGenerateModel().getBeanNameByFirstLetterUpper()).append(">");
		}
		functionMethodBuilder.append(methodModel.getMethodName());
		functionMethodBuilder.append("(");
		functionMethodBuilder.append(generateParameterStr(methodModel));
		functionMethodBuilder.append(") ");
		return functionMethodBuilder.toString();
	}
	
	/**
	 * 生成方法声明
	 * @param methodModel
	 * @return
	 */
	protected String generateMethodDeclare(AbstractMethodGenerateModel methodModel) {
		StringBuilder functionMethodBuilder = new StringBuilder();
		functionMethodBuilder.append("public int ").append(methodModel.getMethodName()).append(" (");
		functionMethodBuilder.append(generateParameterStr(methodModel));
		functionMethodBuilder.append(") ");
		return functionMethodBuilder.toString();
	}
	
}
